package cn.codeguy.component_download;

import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import static cn.dankal.basiclib.util.FileUtils.FILES_DIR;


/**
 * Created by fred
 * Date: 2018/9/14.
 * Time: 09:50
 * classDescription:
 * https://www.jianshu.com/p/92bb85fc07e8
 */
public class DownloadHelper {

    public static void download(String url, String name,
                                String path,
                                DownloadCallback downloadCallback) {
        downloadCallback.onStart();
        Call<ResponseBody> download = DownloadApi.getInstance().download(url);
        download.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if (response.isSuccessful()) {
                    Log.d("Download", "server contacted and has file");
                    boolean writtenToDisk = false;
                    String pathname = FILES_DIR + path + File.separator + name;
                    File dir = new File(FILES_DIR + path);
                    if (!dir.exists()) {
                        dir.mkdirs();
                    }
                    writtenToDisk = writeResponseBodyToDisk(response.body(), pathname, downloadCallback);
                    if (writtenToDisk) {
                        onDownloadComplete(downloadCallback, pathname);
                    } else {
                        onDownloadError(downloadCallback);
                    }
                    Log.e("Download", "file download was a success? " + writtenToDisk);
                } else {
                    Log.e("Download", "server contact failed");
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                onDownloadError(downloadCallback);
            }
        });

        downloadCallback.onInitComplete(download);
    }


    public static void onDownloadComplete(DownloadCallback downloadCallback, String path) {
        downloadCallback.onDownloadComplete("保存成功", path);

    }

    public static void onDownloadError(DownloadCallback downloadCallback) {
        downloadCallback.onDownloadError("保存失败");

    }

    private static void onUpdate(DownloadCallback downloadCallback, long fileSize, long finalFileSizeDownloaded) {
        downloadCallback.onUpdate("下载中：" +
                regularizePrice(Double.valueOf(finalFileSizeDownloaded) / fileSize * 100) + "%");
    }


    //    https://www.jianshu.com/p/92bb85fc07e8
    private static boolean writeResponseBodyToDisk(ResponseBody body, String name, DownloadCallback downloadCallback) {

        try {
            File file = new File(name);

            InputStream inputStream = null;
            OutputStream outputStream = null;

            try {
                byte[] fileReader = new byte[4096];

                long fileSize = body.contentLength();
                long fileSizeDownloaded = 0;

                inputStream = body.byteStream();
                outputStream = new FileOutputStream(file);

                while (true) {
                    int read = inputStream.read(fileReader);

                    if (read == -1) {
                        break;
                    }

                    outputStream.write(fileReader, 0, read);
                    fileSizeDownloaded += read;

                    long finalFileSizeDownloaded = fileSizeDownloaded;
                    onUpdate(downloadCallback, fileSize, finalFileSizeDownloaded);

                    Log.d("Download", "file download: " + fileSizeDownloaded + " of " + fileSize);
                }

                outputStream.flush();

                return true;
            } catch (IOException e) {
                return false;
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                }

                if (outputStream != null) {
                    outputStream.close();
                }
            }
        } catch (IOException e) {
            return false;
        }
    }


    public static String regularizePrice(double price) {
        return String.format(Locale.CHINESE, "%.2f", price);
    }
}
